//
//  QRCodeScanView.swift
//  EyesCare
//
//  Created by TT on 2018/12/20.
//  Copyright © 2018年 qdsg. All rights reserved.
//

import UIKit

protocol QRCodeScanViewDelegate: NSObjectProtocol {
    func scanView(scanView: QRCodeScanView, didClickedTorchSwitch sender: UIButton)
}

class QRCodeScanView: UIView {
    
    weak var delegate: QRCodeScanViewDelegate?

    var rectFrame = CGRect.zero
    private var rectColor = Asset.scanBorder.color
    
    private lazy var rectLayer = CAShapeLayer()
    private lazy var cornerLayer = CAShapeLayer()
    private lazy var lineLayer = CAShapeLayer()
    private lazy var lineAnimation = CABasicAnimation(keyPath: "position")
    
    /// 手电筒按钮
    private lazy var torchSwitchBtn: UIButton = {
        let button = UIButton(type: .custom)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 12)
        button.setTitle("轻触照亮", for: .normal)
        button.setTitle("轻触关闭", for: .selected)
        button.setImage(UIImage(named: "scan_light_off"), for: .normal)
        button.setImage(UIImage(named: "scan_light_on")?.withRenderingMode(.alwaysTemplate), for: .selected)
        button.addTarget(self, action: #selector(torchSwitchClicked(_:)), for: .touchUpInside)
        button.isHidden = true
        return button
    }()
    
    /// 提示语label
    private lazy var tipLabel: UILabel = {
        let label = UILabel()
        label.textColor = UIColor.white.withAlphaComponent(0.6)
        label.textAlignment = .center
        label.font = UIFont.systemFont(ofSize: 13)
        label.text = "将二维码放入框内即可自动扫描"
        label.numberOfLines = 0
        label.sizeToFit()
        return label
    }()
    
    /// 等待指示view
    private lazy var indicatorView: UIActivityIndicatorView = {
        let indicaView = UIActivityIndicatorView(style: .white)
        indicaView.hidesWhenStopped = true
        return indicaView
    }()
    
    init(frame: CGRect, rectFrame: CGRect = .zero, rectColor: UIColor = .clear) {
        super.init(frame: frame)
        if rectFrame.equalTo(.zero) {
            let rectSide = CGFloat(fminf(Float(layer.bounds.width), Float(layer.bounds.height)) * 2 / 3)
            self.rectFrame = CGRect(x: (layer.bounds.width - rectSide) / 2, y: (layer.bounds.height - rectSide) / 2, width: rectSide, height: rectSide)
        } else {
            self.rectFrame = rectFrame
        }
        
        if rectColor.cgColor != UIColor.clear.cgColor {
            self.rectColor = rectColor
        }
        
        drawScanRect()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        // 手电筒按钮
        torchSwitchBtn.frame = CGRect(x: 0, y: 0, width: 60, height: 70)
        torchSwitchBtn.center = CGPoint(x: rectFrame.midX, y: rectFrame.maxY - torchSwitchBtn.bounds.midY)
        torchSwitchBtn.layoutButton(with: .imageTop, space: 10)
    }
    
    /// 开始扫描
    func startScanning() {
        lineLayer.isHidden = false
        lineLayer.add(lineAnimation, forKey: "lineAnimation")
    }
    
    /// 停止扫描
    func stopScanning() {
        lineLayer.isHidden = true
        lineLayer.removeAnimation(forKey: "lineAnimation")
    }
    
    /// 开始扫描动画
    func startIndicating() {
        indicatorView.startAnimating()
    }
    
    /// 停止扫描动画
    func stopIndicating() {
        indicatorView.stopAnimating()
    }
    
    /// 显示手电筒
    func showTorchSwitch() {
        torchSwitchBtn.isHidden = false
        torchSwitchBtn.alpha = 0
        UIView.animate(withDuration: 0.25) {
            self.torchSwitchBtn.alpha = 1.0
        }
    }
    
    /// 隐藏手电筒
    func hideTorchSwitch() {
        UIView.animate(withDuration: 0.25, animations: {
            self.torchSwitchBtn.alpha = 0
        }) { (_) in
            self.torchSwitchBtn.isHidden = true
        }
    }
}

// MARK: - 点击事件
extension QRCodeScanView {
    @objc private func torchSwitchClicked(_ sender: UIButton) {
        if let delegate = delegate {
            delegate.scanView(scanView: self, didClickedTorchSwitch: sender)
        }
    }
}

// MARK: - 画扫描区域
extension QRCodeScanView {
    /// 画扫描框
    func drawScanRect() {
        layer.masksToBounds = true
        
        // 根据自定义的rectFrame画矩形框
        let lineWidth: CGFloat = 0.5
        let rectPath = UIBezierPath(rect: CGRect(x: lineWidth / 2, y: lineWidth / 2, width: rectFrame.size.width - lineWidth, height: rectFrame.size.height - lineWidth))
        rectLayer.fillColor = UIColor.clear.cgColor
        rectLayer.strokeColor = rectColor.cgColor
        rectLayer.path = rectPath.cgPath
        rectLayer.lineWidth = lineWidth
        rectLayer.frame = rectFrame
        layer.addSublayer(rectLayer)
        
        // 根据rectFrame创建矩形拐角路径
        let cornerWidth: CGFloat = 2.0
        let cornerLength = CGFloat(fminf(Float(rectFrame.size.width), Float(rectFrame.size.height)) / 12)
        let cornerPath = UIBezierPath()
        // 左上角
        cornerPath.move(to: CGPoint(x: cornerWidth / 2, y: 0))
        cornerPath.addLine(to: CGPoint(x: cornerWidth / 2, y: cornerLength))
        cornerPath.move(to: CGPoint(x: 0, y: cornerWidth / 2))
        cornerPath.addLine(to: CGPoint(x: cornerLength, y: cornerWidth / 2))
        // 右上角
        cornerPath.move(to: CGPoint(x: rectFrame.size.width, y: cornerWidth / 2))
        cornerPath.addLine(to: CGPoint(x: rectFrame.size.width - cornerLength, y: cornerWidth / 2))
        cornerPath.move(to: CGPoint(x: rectFrame.size.width - cornerWidth / 2, y: 0))
        cornerPath.addLine(to: CGPoint(x: rectFrame.size.width - cornerWidth / 2, y: cornerLength))
        // 右下角
        cornerPath.move(to: CGPoint(x: rectFrame.size.width - cornerWidth / 2, y: rectFrame.size.height))
        cornerPath.addLine(to: CGPoint(x: rectFrame.size.width - cornerWidth / 2, y: rectFrame.size.height - cornerLength))
        cornerPath.move(to: CGPoint(x: rectFrame.size.width, y: rectFrame.size.height - cornerWidth / 2))
        cornerPath.addLine(to: CGPoint(x: rectFrame.size.width - cornerLength, y: rectFrame.size.height - cornerWidth / 2))
        // 左下角
        cornerPath.move(to: CGPoint(x: 0, y: rectFrame.size.height - cornerWidth / 2))
        cornerPath.addLine(to: CGPoint(x: cornerLength, y: rectFrame.size.height - cornerWidth / 2))
        cornerPath.move(to: CGPoint(x: cornerWidth / 2, y: rectFrame.size.height))
        cornerPath.addLine(to: CGPoint(x: cornerWidth / 2, y: rectFrame.size.height - cornerLength))
        // 根据矩形拐角路径画拐角
        cornerLayer.frame = rectFrame
        cornerLayer.path = cornerPath.cgPath
        cornerLayer.lineWidth = cornerPath.lineWidth
        cornerLayer.strokeColor = rectColor.cgColor
        layer.addSublayer(cornerLayer)
        
        // 遮罩+镂空
        layer.backgroundColor = UIColor.black.cgColor
        let maskPath = UIBezierPath(rect: bounds)
        let subPath = UIBezierPath(rect: rectFrame).reversing()
        maskPath.append(subPath)
        let maskLayer = CAShapeLayer()
        maskLayer.fillColor = UIColor(white: 0, alpha: 0.8).cgColor
        maskLayer.path = maskPath.cgPath
        layer.addSublayer(maskLayer)
        
        // 根据rectFrame画扫描线
        let lineFrame = CGRect(x: rectFrame.origin.x + 5.0, y: rectFrame.origin.y, width: rectFrame.size.width - 5.0 * 2, height: 1.5)
        let linePath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: lineFrame.size.width, height: lineFrame.size.height))
        lineLayer.frame = lineFrame
        lineLayer.path = linePath.cgPath
        lineLayer.fillColor = rectColor.cgColor
        lineLayer.shadowColor = rectColor.cgColor
        lineLayer.shadowRadius = 5.0
        lineLayer.shadowOffset = CGSize(width: 0, height: 0)
        lineLayer.shadowOpacity = 1.0
        lineLayer.isHidden = true
        layer.addSublayer(lineLayer)
        
        // 扫描线动画
        let valueX = lineLayer.frame.origin.x + lineLayer.frame.size.width / 2
        let fromValueY = rectFrame.origin.y + lineLayer.frame.size.height
        let toValueY = rectFrame.origin.y + rectFrame.size.height - lineLayer.frame.size.height
        lineAnimation.fromValue = NSValue(cgPoint: CGPoint(x: valueX , y: fromValueY))
        lineAnimation.toValue = NSValue(cgPoint: CGPoint(x: valueX, y: toValueY))
        lineAnimation.repeatCount = MAXFLOAT
        lineAnimation.autoreverses = true
        lineAnimation.duration = 2.0
        
        
        torchSwitchBtn.tintColor = rectColor
        addSubview(torchSwitchBtn)
        
        // 提示语
        tipLabel.center = CGPoint(x: rectFrame.midX, y: rectFrame.maxY + tipLabel.bounds.midY + 12)
        addSubview(tipLabel)
        
        // 等待指示view
        indicatorView.frame = rectFrame
        addSubview(indicatorView)
    }
}
